2049. 统计最高分的节点数目

算法内容

本文件实现 LeetCode 2049「统计最高分的节点数目」。题目要求删除每个节点后,计算剩余各连通块大小的乘积,并统计最高分节点数量。

第一版使用 unordered_map<int, vector<int>> 建树,先通过 DFS 计算每个节点子树大小,再枚举节点计算分数:父侧连通块大小为 n - size[i],每个子树连通块大小为对应子节点的 size。SolutionBetter 针对二叉树性质,用 vector<pair<int, int>> 保存左右孩子,避免 map 和动态 vector 带来的额外开销。整体时间复杂度 O(n),空间复杂度 O(n)。

算法实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include<vector>
#include<iostream>
#include<stack>
#include<queue>
#include<algorithm>
#include<unordered_map>
#include<climits>
#include<set>
using namespace std;

class Solution {
public:
template<class T>
void printVec(const vector<T> &v, const string& head = "") {
if(head != "") {
cout << head << ": ";
}
for (T i : v) {
cout << i << " ";
}
cout << "\n";
}
vector<int> size;
vector<int> parents;
unordered_map<int, vector<int>> children;
int n;
long long max = LONG_LONG_MIN;
int maxn = 0;
int countHighestScoreNodes(vector<int>& parents) {
int n = parents.size();
this->parents = parents;
this->size = vector<int>(n, 1);
this->n = n;
for(int i = 0; i < n; i++) {
getG(i);
}
getSize(0);
for(int i = 0; i < n; i++) {
calScore(i);
}
return maxn;

}


int getSize(int root) {
int childNum = children[root].size();
if(childNum == 0) {
size[root] = 1;
} else if(childNum == 1) {
size[root] += getSize(children[root][0]);
} else {
size[root] += getSize(children[root][0]) + getSize(children[root][1]);
}
return size[root];
}

void calScore(int i) {
int parent = parents[i];
long long res = (parent == -1) ? 1 : (size[0] - size[i]);
vector<int>& childi = children[i];
for(int child : childi) {
res *= size[child];
}
if(res > max) {
max = res;
maxn = 1;
} else if(res == max) {
maxn++;
}
}

void getG(int i) {
int parent = parents[i];
if(parent == -1) {
return;
} else {
children[parent].push_back(i);
}
}
};

int main() {
Solution s;
vector<int> v = {-1,2,0,2,0};
cout << s.countHighestScoreNodes(v) << endl;
return 0;
}

class SolutionBetter {
//不使用map和set
public:
vector<int> parents;
vector<pair<int, int>> children;
vector<int> size;
int n;
long long max = LONG_LONG_MIN;
int maxn = 0;
int countHighestScoreNodes(vector<int>& parents) {
int n = parents.size();
this->parents = parents;
this->children = vector<pair<int, int>>(n, {-1,-1});
this->size = vector<int>(n, 1);
this->n = n;
for(int i = 0; i < n; i++) {
int parent = parents[i];
if(parent == -1) {
continue;
} else {
if(children[parent].first == -1) {
children[parent].first = i;
} else {
children[parent].second = i;
}
}
}
getSize(0);
for(int i = 0; i < n; i++) {
int parent = parents[i];
long long res = (parent == -1) ? 1 : (size[0] - size[i]);
pair<int, int>& childi = children[i];
res *= childi.first != -1 ? size[childi.first] : 1;
res *= childi.second != -1 ? size[childi.second] : 1;
if(res > max) {
max = res;
maxn = 1;
} else if(res == max) {
maxn++;
}
}
return maxn;

}


int getSize(int root) {
pair<int, int> child = children[root];
int a = 0, b = 0;
if(child.first != -1) {
a = getSize(child.first);
}
if(child.second != -1) {
b = getSize(child.second);
}
size[root] = 1 + a + b;
return size[root];
}
};

作者

Meow Meow Liu

发布于

2022-10-05

更新于

2026-10-19

许可协议

评论